﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace ChatData
{
    //new() constraint from here: http://stackoverflow.com/questions/26903/how-can-you-require-a-constructor-with-no-parameters-for-types-implementing-an-in
    /// <summary>
    /// Stores active users including Status and IP address
    /// </summary>
    public class ActiveUserStore<T> where T:IRecord, new()
    {
        protected Dictionary<string, T> thedic = new Dictionary<string, T>();

        public ActiveUserStore()
        {

        }
        public ActiveUserStore(T[] newdata)
        {
            if (newdata != null)
            {
                List<T> temp = newdata.ToList<T>();

                foreach (T item in temp)
                {
                    this.Add(item);
                }
            }
        }
        public int Count()
        {
            return thedic.Count();
        }
        public List<String> AllUsers()
        {
            return thedic.Keys.ToList();
        }
        public bool isLoggedIn(string user)
        {
            return thedic.ContainsKey(user);
        }
        public void Add(string username, string ip, string port, string status)
        {
            try
            {
                T temp = new T();
                temp.Ip = ip;
                temp.Username = username;
                temp.Port = int.Parse(port);
                temp.Status = status;
                thedic.Add(username, temp);
            }
            catch (ArgumentException e)
            {
                T temp = new T();
                temp.Ip = ip;
                temp.Username = username;
                temp.Port = int.Parse(port);
                temp.Status = status;
                thedic[username] = temp;
            }

        }
        public void Add(T temp)
        {
            try
            {

                thedic.Add(temp.Username, temp);
            }
            catch (ArgumentException e)
            {
                thedic[temp.Username] = temp;
            }

        }
        public bool UpdateStatus(string username, string status)
        {
            try
            {
                thedic[username].Status = status;
            }
            catch (ArgumentNullException e)
            {
                throw new InvalidOperationException();
            }
            return true;
        }
        public void Update(string username, string ip, string port, string status)
        {
            try
            {
                T temp = new T();
                temp.Ip = ip;
                temp.Username = username;
                temp.Port = int.Parse(port);
                temp.Status = status; ;

                thedic[username] = temp ;
            }
            catch (ArgumentNullException e)
            {
                throw new InvalidOperationException();
            }

        }
        public void Remove(string user)
        {
            try
            {
                thedic.Remove(user);
            }
            catch (ArgumentNullException e)
            {
                throw new InvalidOperationException();
            }
        }
        public string getStatus(string user)
        {
            return thedic[user].Status;
        }
        public string getIP(string user)
        {
            return thedic[user].Ip.ToString();
        }
        public int getPort(string user)
        {
            return thedic[user].Port;
        }
        public void Update(T user)
        {
            thedic[user.Username]= user;
        }

       public Dictionary<string, T>.Enumerator GetEnumerator()
        {
            return thedic.GetEnumerator();
        }
       public List<T> ToList()
       {
           List<T> thelist = new List<T>();
           foreach(KeyValuePair<string, T> item in thedic){
               thelist.Add(item.Value);
           }
           return thelist;
       }
        
    }
    
}
